package test1;

import service.HasSelfPrivateNum;
import extthread.ThreadA;
import extthread.ThreadB;

/**
　* @Description: TODO
　* @param ${tags}
　* @return ${return_type}
　* @throws
　* @author Merlin
　* @date 2018/6/19 10:27
　*/

/**
 * 实例变量非线程安全
 * 如果多个线程共同访问一个对象中的实例变量，则有可能出现“非线程安全”的问题
 * 用线程访问的对象中如果有多个实例变量，则运行的结果有可能出现交叉的情况。
 */
public class Run {

	public static void main(String[] args) {

		HasSelfPrivateNum numRef = new HasSelfPrivateNum();

		ThreadA athread = new ThreadA(numRef);
		athread.start();

		ThreadB bthread = new ThreadB(numRef);
		bthread.start();
	}

	/**
	 *  HasSelfPrivateNum 未添加 synchronized
	 *  输出结果：
	 *	a set over!
	 	b set over!
	 	b num=200
	 	a num=200
	 *
	 * 本实验室两个线程同时访问一个没有同步的方法，如果两个线程同时操作业务对象中的实例变量，则有可能会出现
	 * “非线程安全”问题。此示例的知识点在签名已经介绍过，只需要在public void addI(String username)反方前加关键字synchronized 即可。
	 *
	 * HasSelfPrivateNum 添加 synchronized
	 * 输出结果：
	 * a set over!
	   a num=100
	   b set over!
	   b num=200
	 	或者：
		 a set over!
		 b set over!
		 a num=100
		 b num=200
	 *可以看到有些打印顺序却不是同步的，是交叉的。为什么是这样的结果呢？
	 *关键字synchronized取得的锁都是对象锁，而不是把一段代码或方法（函数）当做锁，
	 * 所以在上面的示例中，哪个线程先执行带synchronized关键字的方法，哪个线程就持有该方法所属对象的锁
	 * Lock,那么其他线程只能呈等待状态，前提是多个线程访问的是同一个对象。
	 *
	 *
	 *
	 */
}
